﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using IdentityServer4.Extensions;
using IdentityModel.Client;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication;
using IdentityServer4.AccessTokenValidation;

namespace ConsoleClient
{
    class ConsoleHostedService : IHostedService
    {
        public ConsoleHostedService(IServiceProvider serviceProvider
            , ILogger<ConsoleHostedService> logger
            , IConfiguration configuration)
        {
            ServiceProvider = serviceProvider;
            Logger = logger;
            Configuration = configuration;
            CancellationToken = new CancellationToken();
        }

        public IServiceProvider ServiceProvider { get; }
        public ILogger<ConsoleHostedService> Logger { get; }
        public IConfiguration Configuration { get; }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            string input = Console.ReadLine();
            while (!string.Equals(input, "exit", StringComparison.OrdinalIgnoreCase))
            {
                switch (input)
                {
                    default:
                        await GetStudentsListAsync();
                        break;
                }
                input = Console.ReadLine();
            }
        }

        async Task GetStudentsListAsync()
        {
            HttpClient client = new HttpClient();
            string token = await GetTokenByClientAsync();
            client.SetBearerToken(token);
            client.GetAsync("");
        }

        async Task<string> GetTokenByClientAsync()
        {
            HttpClient client = new HttpClient();
            AuthServerOptions options = new();
            Configuration.GetSection(nameof(AuthServerOptions.Authority)).Bind(options);
            var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()
            {
                Address = options.Authority,
                ClientId = options.ClientId,
                ClientSecret = options.ClientSecret,
                GrantType = "client_credentials",
                Scope = "Client"
            }, CancellationToken);
            if (response.IsError)
            {
                throw new Exception(response.Error);
            }
            return response.AccessToken;
        }

        class AuthServerOptions
        {
            public string Authority { get; set; }
            public string ClientId { get; set; }

            public string ClientSecret { get; set; }
        }

        protected CancellationToken CancellationToken { get; set; }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                Logger.LogWarning("按回车键退出程序!");
                Console.ReadLine();
            });
        }
    }
}
